from scapy.all import *
import time
import urllib
import sys


# interface = 'eth0'
interface = 'wlan0'
default_avg_times = 10

def traceroute(dst_ip):
	return traceroute_avg(dst_ip, times_avg = 1)

def traceroute_avg(dst_ip, times_avg=default_avg_times):
    traced_route = []
  
    for ttl in xrange(1, 30):
        rtt_list = []
        for t in xrange(0, times_avg):
            rtt,src,done = ping_for(dst_ip, ttl)
            if rtt:
            	rtt_list.append(rtt)

        rtt_avg = sum(rtt_list)/len(rtt_list) if len(rtt_list) != 0 else "***"
        ip_hop = src if src is not None else "***"
        traced_route += [(ip_hop, rtt_avg)]

       	if done: 
    	   	break

    return traced_route

def ping_for(dst_ip, ttl):
    ping_reply, rtt = ping(dst_ip, ttl)
    if ping_reply:
		return int(rtt * 1000),ping_reply.src,ping_reply[ICMP].type == 0
    else:
		return None,None,False
			
def ping(dst_ip,ttl=64):
	packet = IP(dst=dst_ip, ttl = ttl) / ICMP(type="echo-request") / "TP2 Redes"
	t1 = time.time()
	response = sr1(packet, iface= interface, verbose = 0, timeout = 1 ,retry = 1)
	return (response, time.time() - t1) 
	
def get_city(ip):
	try:
		response = urllib.urlopen('http://freegeoip.net/csv/'+ip).read().replace("\"","").split(',')
		region =  response[4] if response[4] != "" else "Unknown"
		city = response[5] if response[5] != "" else "Unknown"
		lat = response[7] if response[7] != "" else ""
		lon = response[8] if response[8] != "" else ""

		return  (region+", "+ city).ljust(30) + response[2].ljust(20)  + lat + "\t" + lon
	except:
		return ""

def show_ping(dst_ip):
	if ping(dst_ip):
		print "Ping a",dst_ip, "\tOK"
	else:
		print "Ping a",dst_ip, "\tFAIL"

def show_traceroute(dst_ip, avg = False):
	print "Iniciando traceroute a", dst_ip
	trace = traceroute(dst_ip) if not avg else traceroute_avg(dst_ip)
	for index, (host,rtt) in enumerate(trace):
		print index,host.ljust(15),"\t", rtt,"ms".ljust(5), get_city(host)


print "WARNING: Correr como SUDO !!"
if len(sys.argv)>2 and sys.argv[2] == "-avg":
	show_traceroute(sys.argv[1],avg = True)
elif len(sys.argv)>1:
	show_traceroute(sys.argv[1],avg = False)
else:	
	print "Uso: sudo python icmp_client.py HOST [-avg]"
